
#ifndef CONTAINER_CONTAINER_IMPL_H_
#define CONTAINER_CONTAINER_IMPL_H_

#include "common/module-logger.h"
#include "fiber-env/fiber-env.h"
#include "interface/container.h"
#include "interface/logger.h"
#include "./plugin-impl.h"
#include "./service-agent-impl.h"
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

namespace fasmio { namespace container {

class ContainerImpl : public IContainer
{
public:
    explicit ContainerImpl(ILogger* logger);
    virtual ~ContainerImpl();

public:
    virtual bool Initialize();
    virtual void Finalize();

    virtual bool PrepareRequest(INetRequest*);
    virtual bool ServeRequest(INetRequest*, INetResponse**);

private:
    bool load_plugins();
    bool determine_startup_services(std::vector<std::string> *services);
    bool start_services(const std::vector<std::string> &services);

    void stop_services();
    void unload_plugins();

private:
    ILogger* const logger_;
    common::ModuleLogger mlogger_;

    typedef std::shared_ptr<PluginImpl>                     plugin_ptr_t;
    typedef std::map<std::string, plugin_ptr_t>             plugins_t;
    typedef std::map<std::string, std::set<std::string> >   plugin_services_map_t;
    typedef std::map<std::string, plugin_ptr_t>             service_plugin_map_t;
    typedef PluginImpl::service_creator_map_t               service_creator_map_t;
    typedef std::shared_ptr<ServiceAgentImpl>               service_agent_ptr_t;
    typedef std::map<std::string, service_agent_ptr_t>      service_agents_t;
    typedef std::unique_ptr<fiber_env::IMutex>              mutex_ptr_t;

    plugins_t              plugins_;
    plugin_services_map_t  plugin_services_map_;
    service_plugin_map_t   service_plugin_map_;
    service_creator_map_t  service_creator_map_;
    mutex_ptr_t            plugins_lock_;

    service_agents_t       service_agents_;
    mutex_ptr_t            service_agents_lock_;
};

}}  // namespace fasmio::container

#endif  // CONTAINER_CONTAINER_IMPL_H_

